home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
pascal
/
window.zip
/
WBIOS.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-06-17
|
23KB
|
1,065 lines
page 56,132
title WBIOS Window BIOS extension
.sall
;
; Written 1984 By J. Eric Roskos; public domain.
; No support is provided by the author; you must make any desired
; revisions yourself.
;
; This program provides an extension to the BIOS function calls,
; functions 40H-43H. For a description of the calls, see the Turbo
; Pascal program WDEMO.PAS, which also shows the preferred way of
; using the functions. Note, however, that this BIOS extension is
; independent of any particular language, and will work with any
; program that does its I/O through the ROM BIOS's "WRITE_TTY"
; function (the plain MS-DOS display driver does this, for instance).
;
; There are a few enhancements to the IBM BIOS call: TABs are handled
; properly, BELs produce a more bell-like sound, and there is a "Raw"
; mode (although you'll have to add the function call to set it your-
; self) in which all characters are displayed as-is, without translation
; for CR, LF, BEL, etc. There is also an option to turn end-of-line
; wraps on or off, although again you must add the function call.
; To turn these modes on, set the variables "wrap" and "raw" as
; explained below in the comments. (These features were included in
; the program for future expansion, but have never been tested, and
; aren't guaranteed to work).
;
;
; Macros
;
;
; wto: write message to display. Append cr/lf unless crsup=nocr
;
wto macro msg,crsup
local msgstr,around
jmp around
msgstr db msg
ifb <crsup>
db 0DH,0AH
endif
db '$'
around: push ax
push bx
push si
push di
push bp
mov si,offset msgstr
call putc
pop bp
pop di
pop si
pop bx
pop ax
endm
prtreg macro rg,msg ; put register rg with message msg on display
push ax
mov ax,rg
call prtax
wto msg,nocr
pop ax
endm
;
; Code Segment
;
cseg segment para public 'code'
assume cs:cseg,ds:cseg,ss:cseg,es:nothing
org 100H
;
; COM program startup
;
cpstart proc far
jmp near ptr start
cpstart endp
;
; Local Procedures
;
lcpos dw 0E60H
putc proc near ; write a string to display W/O DOS intervention
push es
push ax
mov ax,crt_seg
mov es,ax
mov di,cs:lcpos
putc1:
mov al,cs:[si]
cmp al,'$'
je putc2
cmp al,0dH
jne putc3
mov cs:lcpos,0E60H
mov di,0E60H
jmp putc4
putc3:
mov es:[di],al
inc di
inc di
putc4:
inc si
jmp putc1
putc2:
mov cs:lcpos,di
pop ax
pop es
ret
putc endp
prtnum proc near ; print half a byte on screen
push ds ; this procedure is used by prtax below
push es
push cs
pop ds
push bx
mov bx,crt_seg
mov es,bx
mov bx,offset xltab
xlatb
mov bx,cs:lcpos
mov es:[bx],al
inc cs:lcpos
inc cs:lcpos
pop bx
pop es
pop ds
ret
xltab db '0123456789ABCDEF'
prtnum endp
prtax proc near ; print contents of ax register on screen
push cx ; all registers are preserved
push ax
mov al,ah
mov cl,4
shr al,cl
call prtnum
pop ax
push ax
mov al,ah
and al,0Fh
call prtnum
pop ax
push ax
mov cl,4
shr al,cl
call prtnum
pop ax
push ax
and al,0Fh
call prtnum
pop ax
pop cx
ret
prtax endp
;
; BIOS call dispatcher
;
;
; data area
;
;
; vector to ROM BIOS
;
romoff dw ?
romseg dw ?
;
; display variables
;
active_page db ? ; parameters for wtty (window I/O) proc.
crt_mode db ?
color db 7
rt_edge db 79
bot_edge db 24
lf_edge db 0
top_edge db 0
wd_width db 79 ; window width and height (really the coords of
wd_height db 24 ; bottom corner relative to strt of window)
wrap db 0 ; 0=don't CRLF at right margin, 1=do
raw db 0 ; 0=xlate cr, lf, etc, 1=display w/o xlation
crt_seg dw ? ; segment for CRT display RAM
;
; clock
;
tick dw 0 ; 1/18th second counter
tock dw 0 ; every-5-seconds counter (18.2 Hz adjust)
clk_oset dw 0 ; save area for displaced clock int handler
clk_seg dw 0
;
; window stack:
; 0[wsp] = left edge of window
; 1[wsp] = top edge of window
; 2[wsp] = right edge of window
; 3[wsp] = bottom edge of window
; 4[wsp] = cursor address (2 bytes)
; 6[wsp] = offset of window save area (2 bytes)
; 8[wsp] = segment of window save area (2 bytes)
; 10[wsp] = number of frames (1 byte)
;
wssize equ 13 ; number of bytes in window stack frame
wsframes equ 15 ; number of windows that can be stacked
wsp dw offset wsend ; display window stack pointer
wstack db wssize*wsframes dup (?) ; display window save stack
wsend equ this word ; bottom of stack
db wssize dup (?) ; extra frame in case of user error
;
; window queue: save area for windows
;
wqp dw offset qbase ; next avail byte in window queue
wqsize equ 8192 ; size of window queue - ok to tune
qlim dw ? ; max address in window queue
;
;
temp dw ? ; used when fixing up stack for return
;
; jump table for our BIOS functions
;
jmptab label word
dw offset setwindow
dw offset pushwindow
dw offset rstwindow
dw offset frame
tablen equ $-jmptab
;
; the dispatcher
;
disp proc far
;
; see if it's one of our functions
;
cmp ah,14 ; write TTY function
jne tryrcp
jmp ourfn
tryrcp: cmp ah,3 ; read cursor position
jne tryscp
jmp readcsr
tryscp: cmp ah,2 ; set cursor position
je adjxy ; have to adjust coordinates
cmp ah,6 ; scroll screen up
jne trysd ; have to adjust corners
jmp adjsc
trysd: cmp ah,7 ; scroll screen down
jne tryus ; adjust corners
jmp adjsc
tryus: cmp ah,40H ; one of our new functions?
jl callbios ; no, call the BIOS
jmp ourfn
callbios:
push cs:romseg ; not one of ours; call BIOS
push cs:romoff
ret
;
; adjust x and y coordinates for set-cursor-position
;
adjxy:
push dx ; save caller's dx
add dh,cs:top_edge ; adjust the coordinates
cmp dh,cs:bot_edge
jle adjxy1
; if below the bottom edge, scroll up a line
push ax ; save caller's registers
push bx
push cx
push dx
push si
push di
mov ax,0601H ; scroll up one line
mov cx,0 ; in the current window
mov dh,cs:wd_height
mov dl,cs:wd_width
mov bh,cs:color
int 10H
pop di ; restore caller's registers
pop si
pop dx
pop cx
pop bx
pop ax
mov dh,cs:bot_edge ; now set cursor to bottom
adjxy1: add dl,cs:lf_edge
cmp dl,cs:rt_edge
jle adjxy2
mov dl,cs:rt_edge
; fix up stack so BIOS's IRET will return to
; our adjxy3 label
adjxy2: mov cs:temp,ax ; save ax (can't push it!)
push ax ; a dummy flag register save
push cs ; return cs
mov ax,offset adjxy3 ; return ip
push ax
mov ax,cs:temp ; restore saved ax
jmp callbios ; and call the BIOS
adjxy3:
pop dx ; back from BIOS now: restore caller's
iret ; dx, and return.
;
; adjust corners for scroll
;
adjsc:
push bx
add ch,cs:top_edge ; adjust row posn of upper left
cmp ch,cs:bot_edge
jle adjsc1
mov ch,cs:bot_edge
adjsc1: add cl,cs:lf_edge ; adjust column posn of upper left
cmp cl,cs:rt_edge
jle adjsc2
mov cl,cs:rt_edge
adjsc2: add dh,cs:top_edge ; adjust row posn of lower right
cmp dh,cs:bot_edge
jle adjsc3
mov dh,cs:bot_edge
adjsc3: add dl,cs:lf_edge ; adjust column posn of lower right
cmp dl,cs:rt_edge
jle adjsc4
mov dl,cs:rt_edge
adjsc4: mov bl,cs:bot_edge ; adjust number of lines to scroll
sub bl,cs:top_edge
cmp al,bl
jle adjsc5
mov al,bl
adjsc5: pop bx
jmp callbios
readcsr: ; read cursor position
push ds ; save registers that must be kept
push bx
mov ax,40H ; switch to ROM BIOS data segment
mov ds,ax
mov bl,bh ; get param page number into bx
xor bh,bh
sal bx,1 ; convert to cursor table offset
mov dx,[bx+50H] ; read csr posn from cursor table
mov cx,word ptr 60H ; read csr mode from mode word
push cs ; switch to our data segment
pop ds
sub dh,top_edge ; adjust position for window corner
sub dl,lf_edge
; make sure cursor address is in range -- adjust if not
cmp dh,0 ; c